///////////////////////////////////////////////////////////////////////////
//
//  @ File      :	bn.h
//  @ Author    :	zhoukaifeng<zhoukaifeng@kingsoft.com>
//  @ DateTime  :	2014-10-16 20:40:46 
//  @ Brief     :
//
///////////////////////////////////////////////////////////////////////////

#ifndef __BN__
#define __BN__

#include <string>
#include <vector>

#define T char

class BigNumber:public std::vector<T>
{
public:
    BigNumber();
    BigNumber(int size);
    BigNumber(int size, T defVal);
    BigNumber(std::string initVal);
    BigNumber(const BigNumber& t);
    virtual ~BigNumber();
    
    int         size() const; 
    std::string ToString();
    
    BigNumber& operator =(const BigNumber& t);
    BigNumber operator +(const BigNumber& t);
    BigNumber operator -(const BigNumber& t);
    BigNumber operator *(const BigNumber& t);
    BigNumber operator /(const BigNumber& t);
    BigNumber operator %(const BigNumber& t);

    operator int();
    operator std::string();

public:
    static BigNumber ValueOf(int n);
    static BigNumber ValueOf(std::string val);
    static BigNumber Add(const BigNumber& a, const BigNumber& b);
    static BigNumber Sub(const BigNumber& a, const BigNumber& b);
    static BigNumber Mul(const BigNumber& a, const BigNumber& b);
    static BigNumber Div(const BigNumber& a, const BigNumber& b, BigNumber& rem);
    static BigNumber Mod(const BigNumber& a, const BigNumber& b);
    static BigNumber Exp(const BigNumber& a, const BigNumber& b);
    static BigNumber ExpMod(const BigNumber& a, const BigNumber& b, const BigNumber& mod);

protected:
    static int       _UnsignedCmp(const BigNumber& a, const BigNumber& b);
    static BigNumber _UnsignedAdd(const BigNumber& a, const BigNumber& b);
    static BigNumber _UnsignedSub(const BigNumber& a, const BigNumber& b);
    static BigNumber _UnsignedMul(const BigNumber& a, const BigNumber& b);
    static BigNumber _UnsignedDiv(const BigNumber& a, const BigNumber& b, BigNumber& rem);

    static BigNumber _UnsignedMulBit(const BigNumber& a, T bit);
    static void      _UnsignedMulBitNoCopy(BigNumber& a, T bit);
    static BigNumber _UnsignedDivBit(const BigNumber& a, T bit);
    static void      _UnsignedDivBitNoCopy(BigNumber& a, T bit);

protected:
    int m_negative;

protected:
    static int s_radix;
};

__declspec(selectany) int BigNumber::s_radix = 10;

#endif